flag_example: Vec<String>,
flag_test: Vec<String>,
flag_bench: Vec<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
arg_args: Vec<String>,
}
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
All of the trailing arguments are passed to the benchmark binaries generated
for filtering benchmarks and generally providing options configuring how they
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let ops = ops::TestOptions {
no_run: options.flag_no_run,
flag_example: Vec<String>,
flag_test: Vec<String>,
flag_bench: Vec<String>,
+ flag_locked: bool,
+ flag_frozen: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be built. If it is not given, then the
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-build; args={:?}",
env::args().collect::<Vec<_>>());
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
flag_explain: Option<String>,
arg_command: String,
arg_args: Vec<String>,
+ flag_locked: bool,
+ flag_frozen: bool,
}
const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
Some common cargo commands are (see all commands with --list):
build Compile the current project
execute_main_without_stdin(execute, true, USAGE)
}
+macro_rules! configure_shell {
+ ($config:expr, $options:expr) => (
+ try!($config.configure($options.flag_verbose,
+ $options.flag_quiet,
+ &$options.flag_color,
+ $options.flag_frozen,
+ $options.flag_locked));
+ )
+}
+
macro_rules! each_subcommand{
($mac:ident) => {
$mac!(bench);
on this top-level information.
*/
fn execute(flags: Flags, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(flags.flag_verbose,
- flags.flag_quiet,
- &flags.flag_color));
+ try!(config.configure(flags.flag_verbose,
+ flags.flag_quiet,
+ &flags.flag_color,
+ flags.flag_frozen,
+ flags.flag_locked));
init_git_transports(config);
cargo::util::job::setup();
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_release: bool,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
If the --package argument is given, then SPEC is a package id specification
which indicates which package's artifacts should be cleaned out. If it is not
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-clean; args={:?}", env::args().collect::<Vec<_>>());
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
let opts = ops::CleanOptions {
flag_package: Vec<String>,
flag_lib: bool,
flag_bin: Vec<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
By default the documentation for the local package and all dependencies is
built. The output is all placed in `target/doc` in rustdoc's usual format.
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
If a lockfile is available, this command will ensure that all of the git
dependencies and/or registries dependencies are downloaded and locally
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
let ws = try!(Workspace::new(&root, config));
try!(ops::fetch(&ws));
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-generate-lockfile; args={:?}", env::args().collect::<Vec<_>>());
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
let ws = try!(Workspace::new(&root, config));
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let Options { flag_url: url, flag_reference: reference, .. } = options;
let url = try!(url.to_url().map_err(|e| {
arg_path: Option<String>,
flag_name: Option<String>,
flag_vcs: Option<ops::VersionControl>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-init; args={:?}", env::args().collect::<Vec<_>>());
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let Options { flag_bin, arg_path, flag_name, flag_vcs, .. } = options;
flag_root: Option<String>,
flag_list: bool,
flag_force: bool,
+ flag_frozen: bool,
+ flag_locked: bool,
arg_crate: Option<String>,
flag_vers: Option<String>,
-v, --verbose ... Use verbose output
-q, --quiet Less output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
This command manages Cargo's local set of installed binary crates. Only packages
which have [[bin]] targets can be installed, and all binaries are installed into
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let compile_opts = ops::CompileOptions {
config: config,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let token = match options.arg_token.clone() {
Some(token) => token,
None => {
flag_no_deps: bool,
flag_quiet: Option<bool>,
flag_verbose: u32,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<ExportInfo>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let manifest = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
let options = OutputMetadataOptions {
arg_path: String,
flag_name: Option<String>,
flag_vcs: Option<ops::VersionControl>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-new; args={:?}", env::args().collect::<Vec<_>>());
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let Options { flag_bin, arg_path, flag_name, flag_vcs, .. } = options;
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_list: bool,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
This command will modify the owners for a package on the specified registry (or
default). Note that owners of a package can upload new versions, yank old
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let opts = ops::OwnersOptions {
krate: options.arg_crate,
token: options.flag_token,
flag_list: bool,
flag_allow_dirty: bool,
flag_jobs: Option<u32>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
let ws = try!(Workspace::new(&root, config));
try!(ops::package(&ws, &ops::PackageOpts {
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_manifest_path: Option<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
arg_spec: Option<String>,
}
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
Given a <spec> argument, print out the fully qualified package id specifier.
This command will generate an error if <spec> is ambiguous as to which package
pub fn execute(options: Options,
config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path.clone(), config.cwd()));
let ws = try!(Workspace::new(&root, config));
flag_allow_dirty: bool,
flag_jobs: Option<u32>,
flag_dry_run: bool,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let Options {
flag_token: token,
flag_host: host,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_release: bool,
+ flag_frozen: bool,
+ flag_locked: bool,
arg_args: Vec<String>,
}
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
If neither `--bin` nor `--example` are given, then if the project only has one
bin target it will be run. Otherwise `--bin` specifies the bin target to run,
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
flag_test: Vec<String>,
flag_bench: Vec<String>,
flag_profile: Option<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
The specified target for the current package (or package specified by SPEC if
provided) will be compiled along with all of its dependencies. The specified
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-rustc; args={:?}",
env::args().collect::<Vec<_>>());
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path,
config.cwd()));
flag_example: Vec<String>,
flag_test: Vec<String>,
flag_bench: Vec<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
The specified target for the current package (or package specified by SPEC if
provided) will be documented with the specified <opts>... being passed to the
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path,
config.cwd()));
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_limit: Option<u32>,
- arg_query: Vec<String>
+ flag_frozen: bool,
+ flag_locked: bool,
+ arg_query: Vec<String>,
}
pub const USAGE: &'static str = "
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--limit LIMIT Limit the number of results (default: 10, max: 100)
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let Options {
flag_host: host,
flag_limit: limit,
flag_color: Option<String>,
flag_release: bool,
flag_no_fail_fast: bool,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--no-fail-fast Run all tests regardless of failure
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
All of the trailing arguments are passed to the test binaries generated for
filtering tests and generally providing options configuring how they run. For
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
let empty = Vec::new();
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
arg_spec: String,
}
-v, --verbose ... Use verbose output
-q, --quiet Less output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
The argument SPEC is a package id specification (see `cargo help pkgid`) to
specify which crate should be uninstalled. By default all binaries are
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = options.flag_root.as_ref().map(|s| &s[..]);
try!(ops::uninstall(root, &options.arg_spec, &options.flag_bin, config));
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
This command requires that a `Cargo.lock` already exists as generated by
`cargo build` or related commands.
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-update; args={:?}", env::args().collect::<Vec<_>>());
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd()));
let update_opts = ops::UpdateOptions {
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub const USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
";
pub fn execute(args: Flags, config: &Config) -> CliResult<Option<Error>> {
- try!(config.configure_shell(args.flag_verbose,
- args.flag_quiet,
- &args.flag_color));
+ try!(config.configure(args.flag_verbose,
+ args.flag_quiet,
+ &args.flag_color,
+ args.flag_frozen,
+ args.flag_locked));
let mut contents = String::new();
let filename = args.flag_manifest_path.unwrap_or("Cargo.toml".into());
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_undo: bool,
+ flag_frozen: bool,
+ flag_locked: bool,
}
pub static USAGE: &'static str = "
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
+ --frozen Require Cargo.lock and cache are up to date
+ --locked Require Cargo.lock is up to date
The yank command removes a previously pushed crate's version from the server's
index. This command does not delete any data, and the crate will still be
";
pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
- try!(config.configure_shell(options.flag_verbose,
- options.flag_quiet,
- &options.flag_color));
+ try!(config.configure(options.flag_verbose,
+ options.flag_quiet,
+ &options.flag_color,
+ options.flag_frozen,
+ options.flag_locked));
try!(ops::yank(config,
options.arg_crate,
options.flag_vers,
let ret = if overrides.is_empty() {
// Ensure the requested source_id is loaded
- try!(self.ensure_loaded(dep.source_id(), Kind::Normal));
+ try!(self.ensure_loaded(dep.source_id(), Kind::Normal).chain_error(|| {
+ human(format!("failed to load source for a dependency \
+ on `{}`", dep.name()))
+ }));
match self.sources.get_mut(dep.source_id()) {
Some(src) => try!(src.query(&dep)),
}
}
+ if !ws.config().lock_update_allowed() {
+ let flag = if ws.config().network_allowed() {"--frozen"} else {"--locked"};
+ bail!("the lock file needs to be updated but {} was passed to \
+ prevent this", flag);
+ }
+
// Ok, if that didn't work just write it out
root.open_rw("Cargo.lock", ws.config(), "Cargo.lock file").and_then(|mut f| {
try!(f.file().set_len(0));
/// Create a new HTTP handle with appropriate global configuration for cargo.
pub fn http_handle(config: &Config) -> CargoResult<Easy> {
+ if !config.network_allowed() {
+ bail!("attempting to make an HTTP request, but --frozen was \
+ specified")
+ }
+
// The timeout option for libcurl by default times out the entire transfer,
// but we probably don't want this. Instead we only set timeouts for the
// connect phase as well as a "low speed" timeout so if we don't receive
})
}
-pub fn fetch(repo: &git2::Repository, url: &str,
- refspec: &str, cargo_config: &Config) -> CargoResult<()> {
- // Create a local anonymous remote in the repository to fetch the url
+pub fn fetch(repo: &git2::Repository,
+ url: &str,
+ refspec: &str,
+ config: &Config) -> CargoResult<()> {
+ if !config.network_allowed() {
+ bail!("attempting to update a git repository, but --frozen \
+ was specified")
+ }
with_authentication(url, &try!(repo.config()), |f| {
let mut cb = git2::RemoteCallbacks::new();
cb.credentials(f);
+
+ // Create a local anonymous remote in the repository to fetch the url
let mut remote = try!(repo.remote_anonymous(&url));
let mut opts = git2::FetchOptions::new();
opts.remote_callbacks(cb)
.download_tags(git2::AutotagOption::All);
- try!(network::with_retry(cargo_config, ||{
+ try!(network::with_retry(config, ||{
remote.fetch(&[refspec], Some(&mut opts), None)
}));
Ok(())
use sources::{PathSource, git};
use util::{CargoResult, Config, internal, ChainError, ToUrl, human};
use util::{hex, Sha256, paths, Filesystem, FileLock};
+use util::network;
use ops;
const DEFAULT: &'static str = "https://github.com/rust-lang/crates.io-index";
body.extend_from_slice(buf);
Ok(buf.len())
}));
- try!(handle.perform());
+ try!(network::with_retry(self.config, || {
+ handle.perform()
+ }))
}
let code = try!(handle.response_code());
if code != 200 && code != 0 {
let refspec = "refs/heads/*:refs/remotes/origin/*";
try!(git::fetch(&repo, &url, refspec, &self.config).chain_error(|| {
- internal(format!("failed to fetch `{}`", url))
+ human(format!("failed to fetch `{}`", url))
}));
// git reset --hard origin/master
rustdoc: PathBuf,
target_dir: RefCell<Option<Filesystem>>,
extra_verbose: Cell<bool>,
+ frozen: Cell<bool>,
+ locked: Cell<bool>,
}
impl Config {
rustdoc: PathBuf::from("rustdoc"),
target_dir: RefCell::new(None),
extra_verbose: Cell::new(false),
+ frozen: Cell::new(false),
+ locked: Cell::new(false),
};
try!(cfg.scrape_tool_config());
})
}
- pub fn configure_shell(&self,
- verbose: u32,
- quiet: Option<bool>,
- color: &Option<String>) -> CargoResult<()> {
+ pub fn configure(&self,
+ verbose: u32,
+ quiet: Option<bool>,
+ color: &Option<String>,
+ frozen: bool,
+ locked: bool) -> CargoResult<()> {
let extra_verbose = verbose >= 2;
let verbose = if verbose == 0 {None} else {Some(true)};
let cfg_verbose = try!(self.get_bool("term.verbose")).map(|v| v.val);
self.shell().set_verbosity(verbosity);
try!(self.shell().set_color_config(color.map(|s| &s[..])));
self.extra_verbose.set(extra_verbose);
+ self.frozen.set(frozen);
+ self.locked.set(locked);
Ok(())
}
self.extra_verbose.get()
}
+ pub fn network_allowed(&self) -> bool {
+ !self.frozen.get()
+ }
+
+ pub fn lock_update_allowed(&self) -> bool {
+ !self.frozen.get() && !self.locked.get()
+ }
+
fn load_values(&self) -> CargoResult<()> {
let mut cfg = CV::Table(HashMap::new(), PathBuf::from("."));
but others were accidentally forgotten.
[crates.io]: https://crates.io/
+
+# How can Cargo work offline?
+
+Cargo is often used in situations with limited or no network access such as
+airplanes, CI environments, or embedded in large production deployments. Users
+are often surprised when Cargo attempts to fetch resources from the network, and
+hence the request for Cargo to work offline comes up frequently.
+
+Cargo, at its heart, will not attempt to access the network unless told to do
+so. That is, if no crates comes from crates.io, a git repository, or some other
+network location, Cargo will never attempt to make a network connection. As a
+result, if Cargo attempts to touch the network, then it's because it needs to
+fetch a required resource.
+
+Cargo is also quite aggressive about caching information to minimize the amount
+of network activity. It will guarantee, for example, that if `cargo build` (or
+an equivalent) is run to completion then the next `cargo build` is guaranteed to
+not touch the network so long as `Cargo.toml` has not been modified in the
+meantime. This avoidance of the network boils down to a `Cargo.lock` existing
+and a populated cache of the crates reflected in the lock file. If either of
+these components are missing, then they're required for the build to succeed and
+must be fetched remotely.
+
+As of Rust 1.11.0 (to be released 2016-09-29) Cargo understands a new flag,
+`--frozen`, which is an assertion that it shouldn't touch the network. When
+passed, Cargo will immediately return an error if it would otherwise attempt a
+network request. The error should include contextual information about why the
+network request is being made in the first place to help debug as well. Note
+that this flag *does not change the behavior of Cargo*, it simply asserts that
+Cargo shouldn't touch the network as a previous command has been run to ensure
+that network activity shouldn't be necessary.
+
+Note that Cargo does not yet support vendoring in a first-class fashion, but
+this is a hotly desired feature and coming soon!
[http]
proxy = true
"#);
+ Package::new("foo", "1.0.0").publish();
assert_that(foo.cargo_process("publish").arg("-v"),
execs().with_status(101).with_stderr("\
-[UPDATING] registry `https://[..]`
+[UPDATING] registry `[..]`
[ERROR] invalid configuration for key `http.proxy`
expected a string, but found a boolean in [..]config
"));
assert_that(foo.cargo_process("build").arg("-v"),
execs().with_status(101).with_stderr("\
[UPDATING] git repository `file:///`
-[ERROR] Unable to update file:///
+[ERROR] failed to load source for a dependency on `foo`
+
+Caused by:
+ Unable to update file:///
Caused by:
failed to clone into: [..]
assert_that(p.cargo_process("build"),
execs().with_status(101).with_stderr(&format!("\
[UPDATING] git repository `http://{addr}/foo/bar`
-[ERROR] Unable to update http://{addr}/foo/bar
+[ERROR] failed to load source for a dependency on `bar`
+
+Caused by:
+ Unable to update http://{addr}/foo/bar
Caused by:
failed to clone into: [..]
execs().with_status(101).with_stderr("\
[UPDATING] registry [..]
[UPDATING] git repository [..]
-error: Unable to update file://[..]
+[ERROR] failed to load source for a dependency on `foo`
+
+Caused by:
+ Unable to update file://[..]
Caused by:
Could not find Cargo.toml in `[..]`
assert_that(p.cargo_process("build"),
execs().with_status(101)
.with_stderr("\
-[ERROR] Unable to update file://[..]
+[ERROR] failed to load source for a dependency on `bar`
+
+Caused by:
+ Unable to update file://[..]
Caused by:
failed to read `[..]bar[..]Cargo.toml`
[..]warning: function is never used[..]
"));
}
+
+#[test]
+fn disallow_network() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "bar"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ foo = "*"
+ "#)
+ .file("src/main.rs", "fn main() {}");
+ p.build();
+
+ assert_that(p.cargo("build").arg("--frozen"),
+ execs().with_status(101).with_stderr("\
+[UPDATING] registry `[..]`
+error: failed to load source for a dependency on `foo`
+
+Caused by:
+ Unable to update registry [..]
+
+Caused by:
+ failed to fetch `[..]`
+
+Caused by:
+ attempting to update a git repository, but --frozen was specified
+"));
+}